/*
* introduction: This code is just used to translate LisP to syntex-parse-tree.
* thanks-to https://github.com/maryrosecook/littlelisp
*
* author ufo
* email ufo5260987423@163.com
* date 28 March 2014 
*
* quality Firefox 28.0 +ubuntu 12.04 accept
*/
var Token = function (type, value) {
  this.type = type;
  this.value = value;
};
function tokenize(input){
//	return input.split('"')
//			.map(function(x, i){
//				if (i % 2 == 0)// not in string
//					return x.replace(/\(/g, ' ( ').replace(/\)/g, ' ) ');
//				else// in string
//					return x.replace(/ /g, "!whitespace!");
//			})
//			.join('"')
//			.trim()
//			.split(/\s+/)
//			.map(function(x){
//				return x.replace(/!whitespace!/g, " ");
//			});
	return input.
		replace(/(\(|\))(?=(?:[^"]*"[^"]*")*[^"]*$)/g, ' $1 ').
		trim().
		split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/);
}
function parenthesize(input, list){//just a list processor.list is the ST(not AST)
	if(list == undefined)
		return parenthesize(input, []);
	else{
		var token = input.shift();
		if(token == undefined)//reach the end of input
			return list.pop();//return the whole ST
		else
			if(token == "("){
				list.push(parenthesize(input, []));
				return parenthesize(input, list);
			}else
				if(token == ")")//reach the end of list
					return list;//return part of ST
				else
					return parenthesize(input, list.concat(categorize(token)));
	};
}
function categorize(input){
	if(!isNaN(parseFloat(input)))
		return new Token('literal', parseFloat(input));//'literal' means number or string,here is mumber
	else
		if (input[0] == '"' && input.slice(-1) == '"')
			return new Token('literal', input.slice(1, -1));
		else
			return new Token('identifier', input);
}
function parse(input){
	return parenthesize(tokenize(input),undefined);
}
